package com.irdstudio.rsp.drools.beans;

import com.fasterxml.jackson.annotation.JsonIgnore;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.time.DateFormatUtils;

import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 风控规则执行bean
 */
public class RuleBean {
    /** 规则集id */
    private List<String> ruleCollIds;
    /** 业务流水号 */
    private String bizSerno;
    /** 产品编号 */
    private String prdCode;
    /** 机构代码 */
    private String orgNo;
    /** 流程id */
    private String flowId;
    /** 适配业务系统代码 */
    private String sysCode;
    /** 适配的自定义维度1 */
    private String customDimOne;
    /** 适配的自定义维度2 */
    private String customDimTwo;
    /** 规则集类型 为审批大纲时，规则集id不必传 */
    private String ruleCollType;
    /** 当前执行的规则集id */
    private String currentRuleCollId;
    /** 规则入参 表名为key */
    private Map<String, Object> input;
    /** 规则执行结果 规则id = 结果 */
    private Map<String, Object> output;
    /** 配置参数  规则id + 明细id = 参数值 */
    @JsonIgnore
    private Map<String, Object> param;
    /** 执行值  规则id + 明细id = 参数值 */
    @JsonIgnore
    private Map<String, Object> execu;
    /** 拒绝规则集id */
    @JsonIgnore
    private Set<String> refuseSet;
    /** 通过规则集id */
    @JsonIgnore
    private Set<String> acceptSet;

    /**
     * 默认构造方法，初始化相关属性
     */
    public RuleBean() {
        this.input = new HashMap<>();
        this.output = new HashMap<>();
        this.execu = new HashMap<>();
        this.param = new HashMap<>();
        this.refuseSet = new LinkedHashSet<>();
        this.acceptSet = new LinkedHashSet<>();
    }

    public Map<String, Object> getInput() {
        return input;
    }

    public void setInput(Map<String, Object> input) {
        this.input = input;
    }

    public Map<String, Object> getOutput() {
        return output;
    }

    public void setOutput(Map<String, Object> output) {
        this.output = output;
    }

    @JsonIgnore
    public Map<String, Object> getParam() {
        return param;
    }

    @JsonIgnore
    public Map<String, Object> getExecu() {
        return execu;
    }

    @JsonIgnore
    public Set<String> getRefuseSet() {
        return refuseSet;
    }

    @JsonIgnore
    public Set<String> getAcceptSet() {
        return acceptSet;
    }

    public List<String> getRuleCollIds() {
        return ruleCollIds;
    }

    public void setRuleCollIds(List<String> ruleCollIds) {
        this.ruleCollIds = ruleCollIds;
    }

    public String getBizSerno() {
        return bizSerno;
    }

    public void setBizSerno(String bizSerno) {
        this.bizSerno = bizSerno;
    }

    public String getPrdCode() {
        return prdCode;
    }

    public void setPrdCode(String prdCode) {
        this.prdCode = prdCode;
    }

    public String getOrgNo() {
        return orgNo;
    }

    public void setOrgNo(String orgNo) {
        this.orgNo = orgNo;
    }

    public String getFlowId() {
        return flowId;
    }

    public void setFlowId(String flowId) {
        this.flowId = flowId;
    }

    public String getSysCode() {
        return sysCode;
    }

    public void setSysCode(String sysCode) {
        this.sysCode = sysCode;
    }

    public String getCustomDimOne() {
        return customDimOne;
    }

    public void setCustomDimOne(String customDimOne) {
        this.customDimOne = customDimOne;
    }

    public String getCustomDimTwo() {
        return customDimTwo;
    }

    public void setCustomDimTwo(String customDimTwo) {
        this.customDimTwo = customDimTwo;
    }

    public String getRuleCollType() {
        return ruleCollType;
    }

    public void setRuleCollType(String ruleCollType) {
        this.ruleCollType = ruleCollType;
    }

    public String getCurrentRuleCollId() {
        return currentRuleCollId;
    }

    public void setCurrentRuleCollId(String currentRuleCollId) {
        this.currentRuleCollId = currentRuleCollId;
    }

    /**
     * 回写规则结果
     * @param ruleId
     * @param result
     */
    private void setResult(String ruleId, RESULT result) {
        if (RESULT.ACCEPT == result) {
            this.acceptSet.add(ruleId);
        } else {
            this.refuseSet.add(ruleId);
        }
    }

    /**
     * 记录规则信息
     * @param ruleId
     * @param result
     * @param executeReslut
     */
    public void setResult(String ruleId, RESULT result, String executeReslut) {
        this.setResult(ruleId, result);
        Map<String, Object> collResult = MapUtils.getMap(this.getOutput(), this.getCurrentRuleCollId());
        if (collResult == null) {
            collResult = new HashMap<>();
            this.getOutput().put(this.getCurrentRuleCollId(), collResult);
        }
        RuleResultBean resultBean = new RuleResultBean(ruleId, result.toString(), executeReslut);
        resultBean.setExecDt(DateFormatUtils.format(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss"));
        collResult.put(ruleId, resultBean);
    }

    /**
     * 取存执行值存在的list 如果为空，则设置一个空的list返回
     * @param ruleId
     * @return
     */
    private List<Map<String, Object>> getExecuValList(String ruleId) {
        Map<String, Object> collExecu = MapUtils.getMap(this.execu, this.getCurrentRuleCollId());
        if (collExecu == null) {
            collExecu = new HashMap<>();
            this.execu.put(this.getCurrentRuleCollId(), collExecu);
        }
        List<Map<String, Object>> valList = (List<Map<String, Object>>) collExecu.get(ruleId);
        if (valList == null) {
            valList = new LinkedList<>();
            collExecu.put(ruleId, valList);
        }
        return valList;
    }

    /**
     * 记录规则执行时参数
     * @param ruleId
     * @param key
     * @param val
     * @return
     */
    public boolean setExecuteVal(String ruleId, String key, Object val) {
        List<Map<String, Object>> valList = getExecuValList(ruleId);
        Map<String, Object> valMap = new HashMap<>(1);
        valMap.put(key, val);
        valList.add(valMap);
        return true;
    }

    /**
     * 记录规则执行时参数
     * @param ruleId
     * @param key
     * @param val
     * @return
     */
    public boolean setExecuteVal(String ruleId, Object[] ... pairs) {
        if (pairs == null) {
            return true;
        }
        List<Map<String, Object>> valList = getExecuValList(ruleId);
        Map<String, Object> valMap = new HashMap<>(pairs.length);
        for (Object[] pair : pairs) {
            valMap.put(pair[0].toString(), pair[1]);
        }
        valList.add(valMap);
        return true;
    }

    public static enum RESULT {
        ACCEPT("0", "通过"),
        REFUSE("1", "拒绝");
        private String code;
        private String name;

        private RESULT(String code, String name) {
            this.code = code;
            this.name = name;
        }
        public String toString() {
            return this.code.toLowerCase();
        }
    }

    @JsonIgnore
    public static final String RULE_NAME_KEY = "_NAME";
    @JsonIgnore
    public static final String RULE_TYPE_KEY = "_TYPE";
}
